﻿using System.Collections.Generic;
using System.Collections.Specialized;
using ElectronicCommerce.Framework.Reflection;

namespace ElectronicCommerce.Framework.Utility
{
    /// <summary>
    /// Name Value Collection Extensions
    /// </summary>
    public static class NameValueCollectionExtensions
    {
        /// <summary>
        /// 获取form表单中以namePrefix作为前缀表单的key=>value的集合
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="namePrefix"></param>
        /// <returns></returns>
        public static NameValueCollection GetCollectionStartWithSpecialName(this NameValueCollection collection, string namePrefix)
        {
            NameValueCollection result = new NameValueCollection();

            foreach (string name in collection.AllKeys)
            {
                if (name.ToUpper().Trim().StartsWith(namePrefix.ToUpper().Trim()))
                {
                    result.Add(name, collection.GetValue(name));
                }
            }
            return result;
        }

        /// <summary>
        /// 获取form表单中名字等于valueName的表单的key=>value的集合
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="valueName"></param>
        /// <returns></returns>
        public static NameValueCollection GetCollectionEqualSpecialName(this NameValueCollection collection, string valueName)
        {
            NameValueCollection result = new NameValueCollection();

            foreach (string name in collection.AllKeys)
            {
                if (name.ToUpper().Trim().Equals(valueName.ToUpper().Trim()))
                {
                    result.Add(name, collection.GetValue(name));
                }
            }
            return result;
        }

        /// <summary>
        /// 判断某个Key键是否在请求集合中
        /// Key的大小写不区分，这就要求在页面上传递
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="keyToFind"></param>
        /// <returns></returns>
        private static bool ContainsKey(this NameValueCollection collection, string keyToFind)
        {
            foreach (string str in collection)
            {
                if (str.ToUpperInvariant().Equals(keyToFind.ToUpperInvariant()))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 取字符数据
        /// 注意：key不区分大小写
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetValue(this NameValueCollection collection, string key)
        {
            return collection.GetValue<string>(key, "");
        }

        /// <summary>
        /// 取对应键值的数据, 如不存在返回defaut(T)
        /// 注意：key不区分大小写
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetValue<T>(this NameValueCollection collection, string key)
        {
            return collection.GetValue<T>(key, default(T));
        }

        /// <summary>
        /// 取对应键值的数据, 如不存在返回defatutValue
        /// 注意：key不区分大小写
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T GetValue<T>(this NameValueCollection collection, string key, T defaultValue)
        {
            string value = string.Empty;

            //+++++++++++++++++2008/10/17 by Marble.M.Wu stop the originaly code +++++++++++++
            // if (collection.AllKeys.Contains(key))
            //
            // 我们在取QueryString，Form表单等时需要不区分大小写的判断
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            if (collection.ContainsKey(key))
            {
                value = collection[key];
            }

            T result = defaultValue;
            if (!string.IsNullOrEmpty(value))
            {
                try
                {
                    DefaultConvertible dc = new DefaultConvertible(value);
                    result = (T)dc.ToType(typeof(T), null);
                }
                catch
                {
                    result = defaultValue;
                }
            }

            return result;
        }

        /// <summary>
        /// 取对应键值的数据, 如存在则返回true, 不存在返回false
        /// 注意：key不区分大小写
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        /// <param name="key"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool TryGetValue<T>(this NameValueCollection collection, string key, out T result)
        {
            bool hasValue = true;
            result = default(T);

            string value = string.Empty;

            //+++++++++++++++++2008/10/17 by Marble.M.Wu stop the originaly code +++++++++++++
            // if (collection.AllKeys.Contains(key))
            //
            // 我们在取QueryString，Form表单等时需要不区分大小写的判断
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            if (collection.ContainsKey(key))
            {
                value = collection[key];
            }

            if (!string.IsNullOrEmpty(value))
            {
                try
                {
                    DefaultConvertible dc = new DefaultConvertible(value);
                    result = (T)dc.ToType(typeof(T), null);
                }
                catch
                {
                    hasValue = false;
                }
            }

            return hasValue;
        }

        /// <summary>
        /// 对NameValueCollection中的数据按照key=value进行冒泡排序
        /// </summary>
        /// <param name="bubbleSort"></param>
        /// <returns></returns>
        public static NameValueCollection BubbleSort(this NameValueCollection nameValues)
        {
            List<string> nameValueList = new List<string>();
            foreach (string key in nameValues)
            {
                nameValueList.Add(string.Format("{0}={1}", key, nameValues[key]));
            }
            string[] bubbleSortNameValueAttr = nameValueList.ToArray().BubbleSort();

            NameValueCollection bubbleNameValues = new NameValueCollection();
            foreach (string str in bubbleSortNameValueAttr)
            {
                string[] keyValue = str.Split('=');
                if (keyValue.Length == 2)
                {
                    bubbleNameValues.Add(keyValue[0], keyValue[1]);
                }
            }

            return bubbleNameValues;
        }

        /// <summary>
        /// 使集合只读
        /// </summary>
        /// <param name="nameValues"></param>
        public static void MakeReadOnly(this NameValueCollection nameValues)
        {
            MethodCaller.CallMethod(nameValues, "set_IsReadOnly", true);
        }

        /// <summary>
        /// 使集合可写
        /// </summary>
        /// <param name="nameValues"></param>
        public static void MakeReadWrite(this NameValueCollection nameValues)
        {
            MethodCaller.CallMethod(nameValues, "set_IsReadOnly", false);
        }
    }
}
